import { foreachV } from './utils.js';

let Vue;

export class Store {
    constructor (options) {
        // console.log('store的构造函数');
        let getters = options.getters;
        this.getters = {};
        let computed = {};
        foreachV(getters, (key, fn) => {
            computed[key] = () => {
                return fn(this.state);
            };
            Object.defineProperty(this.getters, key, {
                get: () =>{
                    return this.vm[key];
                }
            });
        });
        
        this.vm = new Vue({
            data: {
                state: options.state
            },
            computed
        })

        // mutations 和 actions
        let mutations = options.mutations;
        this.mutations = {};
        foreachV(mutations, (key, fn) => {
            this.mutations[key] = data => {
                fn(this.state, data);
            }
        });

        let actions = options.actions;
        this.actions = {};
        foreachV(actions, (key, fn) => {
            this.actions[key] = data => {
                fn(this, data);
            }
        });
    }

    get state () {
        return this.vm.state;
    }

    commit = (name, data) => {
        this.mutations[name](data);
    }

    dispatch = (name, data) => {
        this.actions[name](data);
    }
};

// vue.use() 方法会调用插件中的 install 方法并传一个参数，值为Vue 实例
export const install = function (_Vue) {
    Vue = _Vue;
    Vue.mixin({
        beforeCreate () { // 此时 this 已经指向 vue 实例，视图上访问的是那个层级的页面，this 就指向当前的 Vue 实例
            // console.log('混入的插件的beforeCreate', this.$options.name);
            let options = this.$options;
            if (options.store) this.$store = options.store;
            else this.$store = this.$parent && this.$parent.$store
        }
    });
};
